package top.vanchor.flexible.common;

import lombok.extern.slf4j.Slf4j;
import top.vanchor.flexible.config.initexception.BusinessException;
import top.vanchor.flexible.config.initexception.ErrorEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 通用返回结果，服务端响应的数据最终都会封装成此对象
 * @author 98523
 * @param <T>
 */
@Slf4j
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Res<T> {
    /**
     * 状态码：200：成功，其他：失败
     */
    private Integer code;

    /**
     * 提示信息
     */
    private String msg;

    /**
     * 数据
     */
    private T data;

    /*
      动态数据
      private Map<String, Object> map = new HashMap<>();
     */

    /**
     * 通用成功返回结果（默认提示信息：请求成功）
     * @param <T> 泛型标记
     * @return 成功结果
     */
    public static <T> Res<T> success() {
        Res<T> r = new Res<>();
        r.code = 200;
        r.msg = "请求成功";
        return r;
    }

    /**
     * 通用成功返回结果（默认提示信息：请求成功）
     * @param object 获取的数据
     * @param <T> 泛型标记
     * @return 成功结果
     */
    public static <T> Res<T> success(T object) {
        Res<T> r = new Res<>();
        r.data = object;
        r.code = 200;
        r.msg = "请求成功";
        return r;
    }

    /**
     * 通用成功返回结果 （无data）
     * @param msg 提示信息
     * @param <T> 泛型标记
     * @return 成功结果
     */
    public static <T> Res<T> success(String msg) {
        Res<T> r = new Res<>();
        r.data = null;
        r.code = 200;
        r.msg = msg;
        return r;
    }

    /**
     * 通用成功返回结果
     * @param object 获取的数据
     * @param msg 提示信息
     * @param <T> 泛型标记
     * @return 成功结果
     */
    public static <T> Res<T> success(T object, String msg) {
        Res<T> r = new Res<>();
        r.data = object;
        r.code = 200;
        r.msg = msg;
        return r;
    }

    /**
     * 通用失败返回结果（默认走OPERATION_FAILED，即执行失败）
     * @param <T> 泛型标记
     * @return 失败结果
     */
    public static <T> Res<T> error() {
        throw new BusinessException(ErrorEnum.OPERATION_FAILED);
    }

    /**
     * 通用失败返回结果（默认走501，但可以返回动态语句）
     * @param msg 提示信息
     * @param <T> 泛型标记
     * @return 失败结果
     */
    public static <T> Res<T> error(String msg) {
        Res<T> r = new Res<>();
        r.msg = msg;
        r.code = 501;
        return r;
    }

    /**
     * 通用失败返回结果（实体类）
     * @param object 实体类
     * @param <T> 泛型标记
     * @return 失败结果
     */
    public static <T> Res<T> error(T object, String msg) {
        Res<T> r = new Res<>();
        r.data = object;
        r.msg = msg;
        r.code = 501;
        return r;
    }


    /**
     * 特殊的失败接口，根据传入的异常类型，返回对应的错误码和错误信息
     * @param errorEnum 异常类型
     * @param <T> 泛型标记
     * @return 失败结果
     */
    public static <T> Res<T> error(ErrorEnum errorEnum) {
        throw new BusinessException(errorEnum);
    }

    public static <T> Res<T> failed(ErrorEnum errorEnum) {
        Res<T> r = new Res<>();
        r.msg = errorEnum.getErrorMsg();
        r.code = errorEnum.getErrorCode();
        return r;
    }


    /*
      动态数据
      @param key 键
     * @param value 值
     * @return 动态数据
     *
     * public Res<T> add(String key, Object value) {
     *         this.map.put(key, value);
     *         return this;
     *     }
     */

}
